const axios = require('axios').default;
// md5加密
const crypto = require('crypto');
const qs = require('qs');
// 将xml 转化为key
const xml2js = require('xml2js');
const {
    appid,
    mchid,
    notifyUrl,
    mchKey
} = require('../wxconfig.js')
/**
 * 获取密钥
 * @param { Object } params 
 */
function signPayParams(params) {
    const sortedParams = Object.keys(params)
        .sort()
        .reduce((pre, cur) => ({
            ...pre,
            [cur]: params[cur]
        }), {})

    sortedParams.key = mchKey;
    const signResult = crypto.createHash('MD5')
        .update(qs.stringify(sortedParams), {
            // 不编码
            encode: false
        })
        .digest('hex') // 解码
        .toUpperCase(); // 转换为大写
    return signResult
}

/**
 * NATIVE 支付
 * @param { Object } payload 
 */
async function wx_pay(payload) {
    const {
        body,
        orderNo,
        ip,
        totalFee,
        nonceStr
    } = payload;
    // 签名数据
    const paramsNeedSign = {
        appid,
        mch_id: mchid,
        body,
        nonce_str: nonceStr,
        spbill_create_ip: ip,
        notify_url: notifyUrl,
        total_fee: totalFee,
        trade_type: 'NATIVE',
        out_trade_no: orderNo
    }
    const sign = signPayParams(paramsNeedSign)
    const sendXml = `
    <xml>
        <appid>${appid}</appid>
        <body>${body}</body>
        <mch_id>${mchid}</mch_id>
        <nonce_str>${nonceStr}</nonce_str>
        <notify_url>${notifyUrl}</notify_url>
        <out_trade_no>${orderNo}</out_trade_no>
        <spbill_create_ip>${ip}</spbill_create_ip>
        <total_fee>${totalFee}</total_fee>
        <trade_type>NATIVE</trade_type>
        <sign>${sign}</sign>
    </xml>`;
    // 因为axios默认发送的请求是JSON格式的，所以改变下请求头信息
    const result = await axios.post('https://api.mch.weixin.qq.com/pay/unifiedorder', sendXml, {
        headers: {
            'content-type': 'application/xml'
        }
    })
    console.log(result.data)
    return await xml2js.parseStringPromise( result.data, {
        cdata:true,
        // 是否以数组的方式返回
        explicitArrayL:false
    })
}

module.exports = {
    signPayParams,
    wxPay:wx_pay
}
// wx_pay({
//     body:'测试下单',
//     orderNo:'D' + Date.now(),
//     ip:'114.1.2.225',
//     totalFee:1,
//     nonceStr:Date.now(),
// })